/**
 * @file ac_package_operation.c
 * @version 1.1
 * @date August 2024 
 * @author WSH
 *
 * @brief
 *  协议包操作文件
 * @note
 * @details
 *
 * @Copyright (c) 2024 WSH
 */
#include "ac_package_operation.h"
#include "string.h"

#define FREAM_HEAD1 0x55
#define FREAM_HEAD2 0xAA

#define MAX_WAIT_LEN 300 // 最大等待长度,如果超过多少长度还没搜索到结尾,那么直接重置

#ifdef __cplusplus
extern "C" {
#endif

typedef enum{
    PTL_PAR_STATUS_WAIT = 0 ,
    PTL_PAR_STATUS_FIND_END,
}PTL_PAR_STATUS;


// 打包浮点数
uint16_t  ptl_pack_float32(uint8_t *data ,float fin,uint16_t curr_index){
    memcpy(data + curr_index,&fin,sizeof(float));
    return curr_index + sizeof(float);
}

// 解包浮点数
float ptl_depack_float32(uint8_t *datain,int *index){
    float ret = 0.0f;
    memcpy(&ret,datain + *index,sizeof(float));
    *index += 4;
    return ret ;
}

uint16_t  ptl_pack_int32(uint8_t *data ,int data_in,uint16_t curr_index){
    data[curr_index] = (data_in>>24);
    curr_index++;
    data[curr_index] = (data_in>>16);
    curr_index++;
    data[curr_index] = (data_in>>8);
    curr_index++;
    data[curr_index] = (data_in)&0xff;
    curr_index++;
    return curr_index;
}
uint16_t  ptl_pack_uint32(uint8_t *data ,uint32_t data_in,uint16_t curr_index){
    data[curr_index] = (data_in>>24);
    curr_index++;
    data[curr_index] = (data_in>>16);
    curr_index++;
    data[curr_index] = (data_in>>8);
    curr_index++;
    data[curr_index] = (data_in)&0xff;
    curr_index++;
    return curr_index;
}

int  ptl_depack_int32(uint8_t *datain ,int *index){
    int ret = datain[*index+1];
    ret =   (datain[*index]<<24)&0xff000000;
    ret +=  ((datain[*index+1]<<16)&0xff0000);
    ret +=  ((datain[*index+2]<<8)&0xff00);
    ret +=  (datain[*index+3]&0xff);
    *index =  *index+4;
    return ret ;
}

uint32_t  ptl_depack_uint32(uint8_t *datain ,uint32_t *index){
    uint32_t ret = datain[*index+1];
    ret =   (datain[*index]<<24)&0xff000000;
    ret +=  ((datain[*index+1]<<16)&0xff0000);
    ret +=  ((datain[*index+2]<<8)&0xff00);
    ret +=  (datain[*index+3]&0xff);
    *index =  *index+4;
    return ret ;
}


// 打包uint16的数
uint16_t  ptl_pack_uint16(uint8_t *data ,uint16_t u16_in,uint16_t curr_index){
    data[curr_index] = (u16_in>>8);
    curr_index++;
    data[curr_index] = (u16_in)&0xff;
    curr_index++;
    return curr_index;
}
uint16_t  ptl_pack_int16(uint8_t *data ,int16_t u16_in,uint16_t curr_index){
    data[curr_index] = (u16_in>>8);
    curr_index++;
    data[curr_index] = (u16_in)&0xff;
    curr_index++;
    return curr_index;
}
int16_t ptl_depack_int16(uint8_t *datain,int *index){
    int16_t ret = datain[*index+1];
    ret = (datain[*index]<<8)&0xff00;
    ret += (datain[*index+1]&0xff);
    *index =  *index+2;
    return ret ;
}
uint16_t ptl_depack_uint16(uint8_t *datain,int *index){
    uint16_t ret = datain[*index+1];
    ret = (datain[*index]<<8)&0xff00;
    ret += (datain[*index+1]&0xff);
    *index =  *index+2;
    return ret ;
}
uint16_t  ptl_pack_void(uint8_t *data ,uint16_t void_size,uint16_t curr_index){
    // 空余信息留为0xff
    memset(data+curr_index,0xff,void_size);
    return curr_index + void_size;
}

// 打包头
uint16_t ptl_encode_head(PacketSender_t *PacketSender,uint8_t *buffer_out,uint8_t type,uint16_t data_size,uint16_t max_len){
    // 打包数据基础消息
    buffer_out[0] = FREAM_HEAD1;
    buffer_out[1] = FREAM_HEAD2;
    buffer_out[2] = PacketSender->send_sys_id;
    buffer_out[3] = PacketSender->send_id;
    buffer_out[4] = PacketSender->rec_sys_id;
    buffer_out[5] = PacketSender->rec_id;
    buffer_out[6] = type;
    buffer_out[7] = (uint8_t)data_size;
    return  8;
}

/*!
* @brief 初始化
* @param PacketSender: 发送器句柄
* @param send_sys_id: 发送系统ID
* @param send_id:     发送id
* @param rec_sys_id:  接收系统ID
* @param rec_id:      接收部件ID
*/
void PacketSenderInit(PacketSender_t *PacketSender,uint8_t send_sys_id,uint8_t send_id,uint8_t rec_sys_id,uint8_t rec_id){
    PacketSender->send_sys_id = send_sys_id;
    PacketSender->send_id = send_id;
    PacketSender->rec_sys_id = rec_sys_id;
    PacketSender->rec_id = rec_id;
}

uint16_t ptl_data_check(uint8_t *buffer_out,uint16_t curr_len){
    return 0x3322;
}

uint16_t ptl_encode_tail(uint8_t *buffer_out,uint16_t curr_len,uint16_t max_len){
    uint16_t crc = ptl_data_check(buffer_out+2,curr_len-2);
    buffer_out[curr_len] = (uint8_t)(crc>>8);
    curr_len++;
    buffer_out[curr_len] = (uint8_t)(crc&0XFF);
    curr_len++;
    buffer_out[curr_len] = 0x4E;
    curr_len++;
    return curr_len;
}

void ptl_parse_init(ac_pkg_t *pac_pkg){
    memset(pac_pkg->buffer,0,PTL_DEC_BUFFER);
    pac_pkg->curr_count = 0 ;
    pac_pkg->status = PTL_PAR_STATUS_WAIT;
}

void decode_msg_msg(ac_pkg_t *pac_pkg){
    pac_pkg->PacketSender.length      = pac_pkg->buffer[7];
    pac_pkg->PacketSender.type        = pac_pkg->buffer[6];
    pac_pkg->PacketSender.send_sys_id = pac_pkg->buffer[2] ; 
    pac_pkg->PacketSender.send_id     = pac_pkg->buffer[3] ; 
    pac_pkg->PacketSender.rec_sys_id  = pac_pkg->buffer[4] ; 
    pac_pkg->PacketSender.rec_id      = pac_pkg->buffer[5] ; 
}

uint8_t ptl_parse_char(ac_pkg_t *pac_pkg,uint8_t char_in){
    uint16_t buffers;
    uint16_t crc_cal;
    switch (pac_pkg->status){
    case PTL_PAR_STATUS_WAIT:
        if (pac_pkg->buffer[0]==FREAM_HEAD1){
            if(char_in == FREAM_HEAD2){
                pac_pkg->buffer[1] = char_in;
                pac_pkg->curr_count = 2 ; 
                pac_pkg->status = PTL_PAR_STATUS_FIND_END;
                return 1;
            }
        }
        pac_pkg->buffer[0] = char_in;

        break;
    case PTL_PAR_STATUS_FIND_END:
        pac_pkg->buffer[pac_pkg->curr_count] = char_in;

        if(pac_pkg->buffer[pac_pkg->curr_count] == 0x4E){

            // [+]查看总长度是否合理
            if(pac_pkg->curr_count>2){
                buffers = (pac_pkg->buffer[pac_pkg->curr_count-2]<<8)&0xff00 ;
                buffers += pac_pkg->buffer[pac_pkg->curr_count-1] ;
                // [+]检验检查
                crc_cal = ptl_data_check(pac_pkg->buffer,pac_pkg->curr_count);
                if(crc_cal == buffers){
                    // [+]查看数据长度是否匹配
                    if(pac_pkg->buffer[7]== (pac_pkg->curr_count -10)){
                        // [+]收到一包完整的数
                        // 协议分析器
                            // 解包出系统信息
                        decode_msg_msg(pac_pkg);
                        
                        
                        pac_pkg->curr_count = 0 ;
                        pac_pkg->status = PTL_PAR_STATUS_WAIT;
                        return 2;
                    }else{
                        pac_pkg->status = PTL_PAR_STATUS_WAIT;
                    }
                }
            }

            
        }else{
            pac_pkg->curr_count++;
        }

        // 解析看门狗
        if (pac_pkg->curr_count>MAX_WAIT_LEN){
            pac_pkg->status = PTL_PAR_STATUS_WAIT;
        }
        
        break;
    default:
        break;
    }

    return 0;
}

#ifdef __cplusplus
}
#endif
